package com.wangwenjun.concurrency.chapter15;

/**
 * 设计1个生产者和消费者模式,其中消费者是可以自己决定暂停多久的
 * GuardedObject::getResult 值得我们关注
 *
 *
 */
public class GuardedSuspend {


    public static void main(String[] args) throws InterruptedException {

        GuardedObject gb = new GuardedObject();

        new Thread(()->{
            long begin = System.currentTimeMillis();
            Object result = gb.getResult(2000);
            long duration = System.currentTimeMillis()-begin;
            System.out.println("after "+duration+" ms get result");
        }).start();


        Thread.sleep(1_000);

        new Thread(()->{
             gb.setResult("a");
        }).start();


    }


}

class GuardedObject{

    private final Object lock = new Object();

    private Object result;

    public Object getResult(long timeout){
        synchronized (lock){
            long beginTime = System.currentTimeMillis();
            long endTime = 0;
            while (result == null){
                try {
                    lock.wait(timeout);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
                endTime = System.currentTimeMillis();
                long duration = endTime - beginTime;
                if(duration >= timeout){
                    break;
                }else{
                    timeout = timeout - duration;
                }
            }
            return result;
        }
    }


    public void setResult(Object object){
        synchronized (lock){
            this.result = object;
            lock.notifyAll();
        }
    }
}
